//: C20:BasicSequenceOperations.cpp
// The operation available for all the
// basic sequence Containers.

#include <iostream>
#include <vector>
#include <deque>
#include <list>

using namespace std;

template<class ContainerOfInt>
void print(ContainerOfInt& c, char* s = "") {
    cout << s << ":" << endl;

    if (c.empty()) {
        cout << "(empty)" << endl;
        return;
    }

    typename ContainerOfInt::iterator it;
    for (it = c.begin(); it != c.end(); it++) {
        cout << *it << " ";
    }

    cout << endl;
    cout << "size()" << c.size()
        << " max_size() " << c.max_size()
        << " front() " << c.front()
        << " back() " << c.back() << endl;
}

template<class ContainerOfInt>
void basicOps(char* s) {
    cout << "------- " << s << " -------" << endl;
    typedef ContainerOfInt Ci;

    Ci c;
    print(c, "c after default constructor");

    Ci c2(10, 1); // 10 elements, values all 1
    print(c2, "c2 after constructor(10, 1)");

    int ia[] = { 1, 3, 5, 7, 9 };
    const int iasz = sizeof(ia) / sizeof(*ia);

    // Initialize with begin & end iterators:
    Ci c3(ia, ia + iasz);
    print(c3, "c3 after constructor(iter, iter)");

    Ci c4(c2); // Copy-constructor
    print(c4, "c4 after copy-constructor(c2)");

    c = c2; // Assignment operator
    print(c, "c after assign(10, 2)");

    // Assign with begin & end iterators:
    c.assign(ia, ia + iasz);
    print(c, "c after assign(iter, iter)");
    cout << "c using reverse iterators:" << endl;
    typename Ci::reverse_iterator rit = c.rbegin();
    while (rit != c.rend()) {
        cout << *rit++ << " ";
    }
    cout << endl;

    c.resize(4);
    print(c, "c after resize(4)");
    c.push_back(47);
    print(c, "c after push_back(47)");
    c.pop_back();
    print(c, "c after pop_back()");

    typename Ci::iterator it = c.begin();
    it++;
    it++;
    c.insert(it, 74);
    print(c, "c after insert(it, 74)");
    it = c.begin();
    it++;
    c.insert(it, 3, 96);
    print(c, "c after insert(it, 3, 96)");
    it = c.begin();
    it++;
    c.insert(it, c3.begin(), c3.end());
    print(c, "c after inser(it, c3.begin(), c3.end()");
    it = c.begin();
    it++;
    c.erase(it);
    print(c, "c after erase(it)");
    typename Ci::iterator it2 = it = c.begin();
    it++;
    it2++;
    it2++;
    it2++;
    it2++;
    c.erase(it, it2);
    print(c, "c after erase(it, it2)");
    c.swap(c2);
    print(c, "c after swap(c2)");
    c.clear();
    print(c, "c after clear()");
}

int main() {
    basicOps<vector<int> >("vector");
    basicOps<deque<int> >("deque");
    basicOps<list<int> >("list");

    return 0;
} ///:~

